SPDX-FileCopyrightText: 2022 Lina El Ouali & Marin Georges SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
script written in blender 3.3.0 hash 0759f671cclf on windows 11 Giant Steps John Coltrane Martin Georges & Lina el Ouali 2022-2023
LIBRAIRIES
import bpy
import random
import mathCLEAN
Delete ALL objects and related meshes from Blender file.
The file is not saved or reopened in the process.
Select all objects and delete them from the scene.
def clean():
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
bpy.ops.outliner.orphans_purge()
clean()radius_step = 10
current_radius = 10
number_shapes = 12
z_step = 12
for i in range(1, number_shapes):-------- STEP 1: CREATING A COORDONATES NETWORK --------# Circle of fifths# Cuts the circle of fifths into 12 notes to extract coordonates, prepares for the generative figures Adds the center of the circle as a coordonate
current_radius = i * radius_step
bpy.ops.mesh.primitive_circle_add(
vertices=12, scale=(1, 1, 1), radius=current_radius, location=(0, 0, 0)
)
coord = [
tuple(ver.co) for ver in list(bpy.context.selected_objects[0].data.vertices)
]
notes = ["C", "F", "Bb", "Eb", "Ab", "Db", "Gb", "B", "E", "A", "D", "G"]
keys_dict = {} for co, note in zip(coord, notes):
keys_dict[note] = co
keys_dict["O"] = (0, 0, 0)
print(keys_dict)-------- STEP 2: SET THE 12 DIFFERENT CHORDS EXISTING IN THE CIRCLE --------# Creation of a verticles network# Creation of the 12 different shapes according to the chord played. Note: the different shape is refered to as [cord]Vert.
cVert = [keys_dict["C"], keys_dict["Eb"], keys_dict["Ab"], keys_dict["D"]]
fVert = [keys_dict["C"], keys_dict["F"], keys_dict["Ab"], keys_dict["O"]]
bbVert = [keys_dict["D"], keys_dict["F"], keys_dict["Bb"], keys_dict["Ab"]]
ebVert = [keys_dict["D"], keys_dict["G"], keys_dict["Bb"], keys_dict["Eb"]]
abVert = [keys_dict["A"], keys_dict["Eb"], keys_dict["Ab"], keys_dict["Gb"]]
dbVert = [
keys_dict["O"],
keys_dict["Ab"],
keys_dict["Db"],
keys_dict["B"],
keys_dict["E"],
]
gbVert = [keys_dict["E"], keys_dict["Bb"], keys_dict["Db"], keys_dict["Gb"]]
bVert = [
keys_dict["O"],
keys_dict["Bb"],
keys_dict["Eb"],
keys_dict["Gb"],
keys_dict["B"],
]
eVert = [
keys_dict["E"],
keys_dict["D"],
keys_dict["G"],
keys_dict["O"],
keys_dict["Gb"],
]
aVert = [
keys_dict["E"],
keys_dict["A"],
keys_dict["G"],
keys_dict["C"],
keys_dict["O"],
]
dVert = [keys_dict["Gb"], keys_dict["A"], keys_dict["D"], keys_dict["C"]]
gVert = [keys_dict["O"], keys_dict["Gb"], keys_dict["D"], keys_dict["G"]]list of the shapes
myFigures = [
cVert,
fVert,
bbVert,
ebVert,
abVert,
dbVert,
gbVert,
bVert,
eVert,
aVert,
dVert,
gVert,
]-------- STEP 3: LISTS THE ALGORITHM CHOOSES FROM--------# Establishment of different sequences of the introduction part
-INTROS-#
intro1 = [
abVert,
ebVert,
dVert,
gbVert,
bVert,
bbVert,
dbVert,
eVert,
aVert,
gVert,
fVert,
cVert,
]
intro2 = [
fVert,
abVert,
ebVert,
gbVert,
aVert,
bbVert,
gVert,
dVert,
dbVert,
cVert,
eVert,
bVert,
]
intro3 = [
dVert,
bbVert,
aVert,
cVert,
abVert,
gbVert,
gVert,
fVert,
eVert,
bVert,
ebVert,
dbVert,
]
intro4 = [
gVert,
fVert,
dbVert,
aVert,
abVert,
bVert,
bbVert,
cVert,
dVert,
gbVert,
ebVert,
eVert,
]Choosing an intro Establishment of different sequences of the solo part
Intros = [intro1, intro2, intro3, intro4]
myIntro = random.choice(Intros)
print(myIntro) solo1 = [
gVert,
cVert,
aVert,
bbVert,
fVert,
dVert,
bVert,
ebVert,
gbVert,
eVert,
dbVert,
abVert,
]
solo2 = [
cVert,
fVert,
bbVert,
gVert,
gbVert,
dbVert,
ebVert,
eVert,
bVert,
aVert,
abVert,
dVert,
]
solo3 = [
dVert,
bVert,
ebVert,
fVert,
gVert,
dbVert,
aVert,
eVert,
abVert,
bbVert,
gbVert,
cVert,
]
solo4 = [
bbVert,
dbVert,
gVert,
abVert,
dVert,
gVert,
abVert,
dVert,
cVert,
fVert,
aVert,
gbVert,
]choosing a solo
Solos = [solo1, solo2, solo3, solo4]
mySolo = random.choice(Solos)
print(mySolo)-------- STEP 1: PREPARING THE PARAMETERS --------# ----VARIABLES
radius_step = 10
current_radius = 10
z_step = 12----FACES Defining the number of faces as the polygons have different numbers of edges
myFacesFour = [(0, 1, 2, 3)]
myFacesFive = [(0, 1, 2, 3, 4)]-------- STEP 2: CREATE A FACE FOR THE INTRO --------#
for note in range(0, 1):
myVerticles = myIntro[note]
if len(myIntro[note]) == 4:
myFaces = myFacesFour
else:
myFaces = myFacesFive
print(myFaces)creation of the mesh and the object
myMesh = bpy.data.meshes.new("polyMesh1")
myObject = bpy.data.objects.new("poly1", myMesh)link object to collection
myCollection = bpy.context.collection
myCollection.objects.link(myObject)
myMesh.from_pydata(myVerticles, [], myFaces)rotate mesh around the y axis
degrees = -90
radians = math.radians(degrees)
myObject.rotation_euler.y = radiansrotate mesh around the z axis
degrees = z_step * i
radians = math.radians(degrees)
myObject.rotation_euler.z = radiansrotate mesh around the y axis
degrees = 50
radians = math.radians(degrees)
myObject.rotation_euler.x = radiansconvert mesh into a curve
bpy.ops.object.convert(target="CURVE")-------- STEP 1: PREPARING THE PARAMETERS --------# ----VARIABLES
radius_step = 10
current_radius = 10
z_step = 10----FACES
myFacesFour = [(0, 1, 2, 3)]
myFacesFive = [(0, 1, 2, 3, 4)]-------- STEP 2: CREATE THE FACES --------# ----VARIABLES
for note in range(0, 11):SHORTCUT
myVerticles2 = mySolo[note]
if len(mySolo[note]) == 4:
myFaces = myFacesFour
else:
myFaces = myFacesFive
print(myFaces)creation of the mesh and the object
myMesh2 = bpy.data.meshes.new("polyMesh2")
myObject2 = bpy.data.objects.new("poly2", myMesh2)link object to collection
myCollection = bpy.context.collection
myCollection.objects.link(myObject2)fill the mesh with the verticles information (position of verticles & connection to make face)
myMesh2.from_pydata(myVerticles2, [], myFaces)rotations
myObject2.rotation_euler.y = math.radians(note * 30)
current_radius = note * radius_step
degrees = -30
radians = math.radians(degrees)
myObject2.rotation_euler.x = radians
degrees = z_step * note
radians = math.radians(degrees)
myObject2.rotation_euler.z = radiansall_objects = list(bpy.data.objects)check if objects are named poly
all_poly_objects = []
for obj in all_objects:
if "poly2" in obj.name:add polys to new list
all_poly_objects.append(obj)add and apply SOLIDIFY modifier to shapes
bpy.ops.object.select_all(action="DESELECT")
for poly in all_poly_objects:Apply modifier to selected object
poly.select_set(True) # selected object
bpy.context.view_layer.objects.active = poly
bpy.ops.object.modifier_add(type="SOLIDIFY")
bpy.context.object.modifiers["Solidify"].thickness = 4
bpy.ops.object.modifier_apply(modifier="Solidify")
poly.select_set(False)check if objects are named poly
all_poly_objects = []
for obj in all_objects:
if "poly1" in obj.name:add polys to new list
all_poly_objects.append(obj)add and apply SOLIDIFY modifier to shapes
bpy.ops.object.select_all(action="DESELECT")
for poly in all_poly_objects:Apply modifier to selected object
poly.select_set(True) # selected object
bpy.context.view_layer.objects.active = poly
bpy.ops.object.modifier_add(type="CURVE")
bpy.ops.object.convert(target="CURVE")
bpy.context.object.data.bevel_depth = 2shade smooth
bpy.ops.object.shade_smooth()